package me.ezitku.base.Socket.Tcp

import com.pawegio.kandroid.runOnUiThread
import me.ezitku.base.File.byteArrayToInt
import me.ezitku.base.File.toByteArray
import me.ezitku.base.Socket.connectTcpSocket
import me.ezitku.base.Socket.model.FileInfo
import me.ezitku.base.Socket.sendBytes
import me.ezitku.base.extensions.write
import java.io.*
import java.net.Socket


object SocketFile {
    var ipAddress = ""
}

fun Socket.IO(action: () -> Unit) {

    getMessage {
        if (it.startsWith(TCP_CONST.IO)) {
            action()
        }
    }

}


fun getFileList(filePath: String, action: (ArrayList<FileInfo>) -> Unit) {
    connectTcpSocket(SocketFile.ipAddress) {
        var input = it.getInputStream()
        var output = it.getOutputStream()
//        it.sendBytes(createOperation(TCP_CONST.GET_FILE_LIST),filePath.toByteArray())
        output.write(createOperation(TCP_CONST.GET_FILE_LIST))
        println("writed [ ${TCP_CONST.GET_FILE_LIST} ] OPeration---")
        output.write(filePath.toByteArray())
        println("writed [ $filePath  ]---")
        //output.flush()
//        var operation = it.operation
//        if (operation == TCP_CONST.RECEIVER_FILE_LIST) {
//            var receiver = it.getMessage()
//            println("received FIle List Message")
//            var result = receiver.toArrayList(FileInfo::class.java)
//            println("file list to ArrayList Completed")
//            action.invoke(result)
//        }
    }
}

fun sendFileList(filePath: String, ipAddress: String) {
    connectTcpSocket(ipAddress) {
        //        var input = it.getInputStream()
        var output = it.getOutputStream()



        output.write(createOperation(TCP_CONST.RECEIVER_FILE_LIST))
        println("writed ${TCP_CONST.RECEIVER_FILE_LIST} OPeration---")
        var sendMessage = getFileInfo(filePath)
        sendMessage.write ="fileLists.txt"
        var input = ByteArrayInputStream(sendMessage.toByteArray())

        var buf = ByteArray(DEFAULT_BUFFER_SIZE)
        println("input.available(): ${input.available()}")
        var length = input.read(buf, 0, buf.size)
        while (length != -1) {
            println("input.available(): ${input.available()}")
            output.write(buf, 0, length)
            //output.flush()
            length = -1
            if (input.available() > 0)
                length = input.read(buf, 0, buf.size)
        }
        println("writed File List Info---")


    }

}


fun Socket.receiverFiles(fileName: String, done: (String) -> Unit): ArrayList<FileInfo> {
    //if (operation.startsWith(TCP_CONST.GET_FILES))
    var files = ArrayList<FileInfo>()
    if (operation == TCP_CONST.RECEIVER_FILE_LIST) {
        val inputStream = getInputStream()
        val buf = ByteArray(DEFAULT_BUFFER_SIZE)
        var length = inputStream.read(buf, 0, buf.size)
        var result = ""
        while (length != -1) {
            result += String(buf, 0, length)
            length = -1
            if (inputStream.available() > 0) {
                length = inputStream.read(buf, 0, buf.size)
            }
        }
        runOnUiThread { done.invoke(result) }
    }
    return files
}

fun Socket.getFileList(filePath: String, action: (ArrayList<FileInfo>) -> Unit) {
    sendBytes(createOperation(TCP_CONST.GET_FILE_LIST), filePath.toByteArray())
    val opr = operation
    if (opr == TCP_CONST.RECEIVER_FILE_LIST) {
        val fileList = getMessage()
//        println(fileList)
        fileList.write = "file.txt"
        //runOnUiThread { action.invoke(fileList.toArrayList(FileInfo::class.java)) }
    }

}

fun Socket.sendFileList(filePath: String) {
    sendBytes(createOperation(TCP_CONST.RECEIVER_FILE_LIST), getFileInfo(filePath).toByteArray())

}


fun getFileInfo(fileName: String): String {
    var file = File(fileName)
    var files = file.listFiles()
    var fileInfos = ArrayList<FileInfo>()
    files.forEach {
        var info = FileInfo()
        info.absolutePath = it.absolutePath
        info.isFile = !it.isDirectory
        info.fileName = it.name
        fileInfos.add(info)
    }
    //println(fileInfos.toJson())
    return ""
}


val Socket.operation: String
    get() {
        var inputStream = getInputStream()
        val sumBuf = ByteArray(4)
        inputStream.read(sumBuf, 0, sumBuf.size)
        val operBuf = ByteArray(byteArrayToInt(sumBuf))
        var length = inputStream.read(operBuf, 0, operBuf.size)
        var res = String(operBuf, 0, length)
        return res

    }

val InputStream.operation: String
    get() {
        //var inputStream = getInputStream()
        val sumBuf = ByteArray(4)
        read(sumBuf, 0, sumBuf.size)
        val operBuf = ByteArray(byteArrayToInt(sumBuf))
        var length = read(operBuf, 0, operBuf.size)
        var res = String(operBuf, 0, length)
        return res

    }


fun createOperation(operation: String): ByteArray {
    val sendMsg = operation.toByteArray()
    val sendMsgSize = sendMsg.size
    return sendMsgSize.toByteArray.plus(sendMsg)
}


fun Socket.getMessage(): String {
    var input = getInputStream()
    var buf = ByteArray(DEFAULT_BUFFER_SIZE)
    var length = input.read(buf, 0, buf.size)
    var result = ""
    while (length != -1) {
        result += String(buf, 0, length)
        length = input.read(buf, 0, buf.size)
    }
    return result
}


fun InputStream.getMessage(): String {
//    var input = getInputStream()
    var buf = ByteArray(DEFAULT_BUFFER_SIZE)
    var length = this.read(buf, 0, buf.size)
    var result = ""
    while (length != -1) {
        result += String(buf, 0, length)
        length = -1
        if (available() > 0)
            length = this.read(buf, 0, buf.size)
    }
    return result
}



fun InputStream.messageWrite() {
    var output = FileOutputStream(File("/sdcard/fileLists.txt"))
    var buf = ByteArray(DEFAULT_BUFFER_SIZE)
    println("available: ${available()}")
    var length = this.read(buf, 0, buf.size)

    while (length != -1) {
        println("available: ${available()}")
        output.write(buf,0,buf.size)
        output.flush()
        length = -1
        if (available() > 0)
            length = this.read(buf, 0, buf.size)
    }
   // return result
}


fun writeRead(input: InputStream, output: OutputStream) {
    var buf = ByteArray(DEFAULT_BUFFER_SIZE)
    var length = input.read(buf, 0, buf.size)
    while (length != -1) {
        output.write(buf, 0, length)
        output.flush()
        length = input.read(buf, 0, buf.size)
    }
}
